package com.medicine.product.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.medicine.product.dto.HospitalOrderListVo;
import com.medicine.product.dto.OrderDto;
import com.medicine.product.entity.Category;
import com.medicine.product.fengin.VyyBalanceApiClient;
import com.medicine.product.mapper.CategoryMapper;
import com.medicine.product.mapper.TbbalanceMapper;
import com.medicine.product.mapper.TbdoctorMapper;
import com.medicine.product.param.CategoryParam;
import com.medicine.product.utils.DateUtils;
import com.medicine.product.utils.ExByteArrayOutputStream;
import com.medicine.product.utils.ExcelExportUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.zip.Adler32;
import java.util.zip.CheckedOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;


@Service
public class TestService extends ServiceImpl<CategoryMapper, Category> {

    @Autowired
    CategoryMapper categoryMapper;
    @Autowired
    private TbdoctorMapper tbdoctorMapper;
    @Autowired
    private TbbalanceMapper tbbalanceMapper;
    @Autowired
    private VyyBalanceApiClient vyyBalanceApiClient;


    public List<HospitalOrderListVo> exOrderList(OrderDto orderDto) throws IOException {
        //计算环比
        String orderBy = "";
        Date date = new Date();
        orderDto.setStartTime(DateUtils.getStartMoth());
        orderDto.setEndTime(DateUtils.getEndMoth());
        if (orderDto.getOrderBy().contains("y2y") || orderDto.getOrderBy().contains("m2m")
                || orderDto.getOrderBy().contains("grossProfit")) {
            orderBy = orderDto.getOrderBy();
            orderDto.setOrderBy(null);
        }
        if (StringUtils.isNotEmpty(orderDto.getKey())) {
            //通过医生名称查找社区id
            List<String> hospitalIds = tbdoctorMapper.findHospitalIdByDoctorName(orderDto.getKey());
            if (hospitalIds != null && hospitalIds.size() > 0) {
                orderDto.setKey(null);
                orderDto.setHospitalIds(hospitalIds);
            }
        }

        List<HospitalOrderListVo> list = tbbalanceMapper.orderList(orderDto);
        //计算日期范围相隔天数
        long diffTime = orderDto.getStartTime() == null || orderDto.getEndTime() == null ? 0L :
                DateUtils.diffTime(orderDto.getStartTime(), orderDto.getEndTime());
        orderDto.setDiffTime(diffTime + 1);
        orderDto.setRateType(1);
        List<HospitalOrderListVo> rateV2mon = tbbalanceMapper.rateToHospital(orderDto);
        orderDto.setRateType(2);
        List<HospitalOrderListVo> rate2year = tbbalanceMapper.rateToHospital(orderDto);
        //获取分成比例
        countToList(list, rateV2mon, rate2year);
        //排序
        if (orderBy.contains("m2m")) {
            list.stream().sorted(Comparator.comparing(HospitalOrderListVo::getM2m)).collect(Collectors.toList());
        }
        if (orderBy.contains("y2y")) {
            list.stream().sorted(Comparator.comparing(HospitalOrderListVo::getY2y)).collect(Collectors.toList());
        }
        if (orderBy.contains("grossProfit")) {
            list.stream().sorted(Comparator.comparing(HospitalOrderListVo::getGrossProfit)).collect(Collectors.toList());
        }

        //xxxx年xx月社区医院对账单
        String fileData = DateUtils.getHeadMoth()+"社区医院对账单";

        Map<String, List<HospitalOrderListVo>> classMap = list.stream().collect(Collectors.groupingBy(HospitalOrderListVo::getSarea));


        File zipFile = File.createTempFile(fileData, ".zip");
        FileOutputStream f = new FileOutputStream(zipFile);
        /**
         * 作用是为任何OutputStream产生校验和
         * 第一个参数是制定产生校验和的输出流，第二个参数是指定Checksum的类型 （Adler32（较快）和CRC32两种）
         */
        CheckedOutputStream csum = new CheckedOutputStream(f, new Adler32());
        // 用于将数据压缩成Zip文件格式
        ZipOutputStream zos = new ZipOutputStream(csum);

        for (int i=0;i<classMap.size();i++){
            List<HospitalOrderListVo> hospitalOrderListVos = classMap.get(i);
            Map<String, List<HospitalOrderListVo>> voMap = hospitalOrderListVos.stream().collect(Collectors.groupingBy(HospitalOrderListVo::getShospitalid));
            for(int j=0;j<voMap.size();j++){
                List<HospitalOrderListVo> h = voMap.get(j);
                String fileName = h.get(0).getShname()+".xlsx";
                String invoiceName = h.get(0).getInvoiceName();
                List<Map<String,String>> maps = h.stream().map(t->t.toMap()).collect(Collectors.toList());
                ExByteArrayOutputStream baos = ExcelExportUtil.toExcel(HospitalOrderListVo.getTagNameList(),maps,fileName,"2",fileData,invoiceName);
                InputStream inputStream = ExcelExportUtil.streamTran(baos);
                zos.putNextEntry(new ZipEntry(fileData+h.get(0).getSarea()+"/"+fileName));
                int bytesRead = 0;
                // 向压缩文件中输出数据
                while((bytesRead=inputStream.read())!=-1){
                    zos.write(bytesRead);
                }
                inputStream.close();
                zos.closeEntry(); // 当前文件写完，定位为写入下一条项目

//                String url = UploadFileUtils.uploadFile(ExcelExportUtil.streamTran(baos),fileName,"export/"+fileData+h.get(0).getSarea(),childOssBucket);
            }
        }
        zos.close();

//        String url = UploadFileUtils.uploadFile(zipFile,"export/",childOssBucket,true);

        return null;
    }

    public void countToList(List<HospitalOrderListVo> orderList, List<HospitalOrderListVo> rateV2mon,
                            List<HospitalOrderListVo> rate2year) {
        orderList.forEach(p -> {
            //计算环比
            rateV2mon.stream().filter(e -> e.getShospitalid().equals(p.getShospitalid()) && e.getGmv().compareTo(BigDecimal.ZERO) > 0).findFirst().ifPresent(f -> {
                if (p.getGmv() != null && p.getGmv().compareTo(BigDecimal.ZERO) > 0) {
                    BigDecimal divide = (p.getGmv().divide(f.getGmv(), 2, BigDecimal.ROUND_HALF_UP)).multiply(new BigDecimal(100));
                    p.setM2m(divide);
                } else {
                    p.setM2m(BigDecimal.ZERO);
                }

            });
            //计算同比
            rate2year.stream().filter(e -> e.getShospitalid().equals(p.getShospitalid()) && e.getGmv().compareTo(BigDecimal.ZERO) > 0).findFirst().ifPresent(f -> {
                if (p.getGmv() != null && p.getGmv().compareTo(BigDecimal.ZERO) > 0) {
                    BigDecimal divide = (p.getGmv().divide(f.getGmv(), 2, BigDecimal.ROUND_HALF_UP)).multiply(new BigDecimal(100));
                    p.setY2y(divide);
                } else {
                    p.setY2y(BigDecimal.ZERO);
                }
            });
            //毛利 = 营利 - 医生成本 - 护士成本-医院补贴
            p.setGrossProfit(p.getOrderSum().subtract(p.getTotaldprice()).subtract(p.getIprice()).subtract(p.getHospitalPrice()));
            if (p.getY2y() == null) {
                p.setY2y(BigDecimal.ZERO);
            }
            if (p.getM2m() == null) {
                p.setM2m(BigDecimal.ZERO);
            }
        });
    }

    public String list(){
        String balance = vyyBalanceApiClient.balanceList().getData();
        return balance;
    }

}
